/**************************************************************************
 * $RCSfile: Insert.java,v $  $Revision: 1.3 $  $Date: 2009/01/05 10:09:22 $
 *
 * $Log: Insert.java,v $
 * Revision 1.3  2009/01/05 10:09:22  @author simplefan
 * *** empty log message ***
 *
 * Revision 1.2  2009/01/04 01:21:04  @author simplefan
 * *** empty log message ***
 *
 **************************************************************************/
package com.simplefan.meta.engine.persister.entity;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import org.hibernate.dialect.Dialect;
import org.hibernate.type.LiteralType;

/**
 * An SQL <tt>INSERT</tt> statement
 *
 * @author simplefan
 */
public class Insert {
  private Dialect dialect;

  private String tableName;

  private String comment;

  private Map<String, String> columns = new LinkedHashMap<String, String>();

  public Insert(Dialect dialect){
    this.dialect = dialect;
  }

  protected Dialect getDialect() {
    return dialect;
  }

  public Insert setComment(String comment) {
    this.comment = comment;
    return this;
  }

  public Insert addColumn(String columnName) {
    return addColumn(columnName, "?");
  }

  public Insert addColumns(String [] columnNames) {
    for(int i = 0; i < columnNames.length; i++) {
      addColumn(columnNames[i]);
    }
    return this;
  }

  public Insert addColumns(String [] columnNames, boolean [] insertable) {
    for(int i = 0; i < columnNames.length; i++) {
      if(insertable[i]) {
        addColumn(columnNames[i]);
      }
    }
    return this;
  }

  public Insert addColumn(String columnName, String value) {
    columns.put(columnName, value);
    return this;
  }

  public Insert addColumn(String columnName, Object value, LiteralType type) throws Exception {
    return addColumn(columnName, type.objectToSQLString(value, dialect));
  }

  public Insert addIdentityColumn(String columnName) {
    String value = dialect.getIdentityInsertString();
    if(value != null) {
      addColumn(columnName, value);
    }
    return this;
  }

  public Insert setTableName(String tableName) {
    this.tableName = tableName;
    return this;
  }

  public String toStatementString() {
    StringBuffer buf = new StringBuffer(columns.size() * 15 + tableName.length() + 10);
    if(comment != null) {
      buf.append("/* ").append(comment).append(" */ ");
    }
    buf.append("insert into ").append(tableName);
    if(columns.size() == 0) {
      buf.append(' ').append(dialect.getNoColumnsInsertString());
    }
    else {
      buf.append(" (");
      Iterator iter = columns.keySet().iterator();
      while(iter.hasNext()) {
        buf.append(iter.next());
        if(iter.hasNext()) {
          buf.append(", ");
        }
      }
      buf.append(") values (");
      iter = columns.values().iterator();
      while(iter.hasNext()) {
        buf.append(iter.next());
        if(iter.hasNext()) {
          buf.append(", ");
        }
      }
      buf.append(')');
    }
    return buf.toString();
  }
}
